package controllers

import (
	"encoding/json"
	"errors"
	"os"
	"strconv"

	md "gitee.com/countpoison/youbei/models"
	beego "github.com/beego/beego/v2/adapter"
)

// uploadfile ...
type uploadfile struct {
	ID        string `json:"id"`
	FileName  string `json:"filename"`
	SaveDir   string `json:"savedir"`
	Size      int64  `json:"size"`
	PacketNum int64  `json:"packetnum"`
}

//EnableServer 启动本地存储
func (c *MainController) EnableServer() {
	ob := new(md.Yserver)
	c.APIReturn(500, "解析失败", json.Unmarshal(c.Ctx.Input.RequestBody, ob))
	c.APIReturn(500, "服务启动失败", ob.EnableYserver())
	c.APIReturn(200, "服务启动成功", nil)
}

//Yserverlist 本地存储查询
func (c *MainController) Yserverlist() {
	ys := md.Yserver{}
	bol, err := md.Localdb().Get(&ys)
	c.APIReturn(500, "查询Yserver失败", err)
	if !bol {
		c.APIReturn(500, "Yserver不存在", errors.New("Yserver不存在"))
	}
	ys.Port, err = beego.AppConfig.Int("httpport")
	c.APIReturn(500, "端口获取失败", err)
	c.APIReturn(200, "获取成功", ys)
}

//DisableServer 关闭本地存储
func (c *MainController) DisableServer() {
	ob := new(md.Yserver)
	c.APIReturn(500, "解析失败", json.Unmarshal(c.Ctx.Input.RequestBody, ob))
	c.APIReturn(500, "服务关闭失败", ob.EnableYserver())
	c.APIReturn(200, "服务关闭成功", nil)
}

//UploadFile 新增上传文件任务
func (c *LoginController) UploadFile() {
	ys := md.Yserver{}
	bol, err := md.Localdb().Get(&ys)
	c.APIReturn(500, "查询Yserver失败", err)
	if !bol {
		c.APIReturn(500, "Yserver不存在", errors.New("Yserver不存在"))
	}
	if !ys.Enable {
		c.APIReturn(500, "Yserver未启动", errors.New("Yserver未启动"))
	}
	if c.GetString("username") != ys.Username || c.GetString("password") != ys.Password {
		c.APIReturn(500, "账号密码错误", errors.New("账号密码错误"))
	}
	var ob uploadfile

	ob.ID = c.Ctx.Input.Param(":id")
	ob.FileName = c.GetString("filename")
	ob.Size, err = c.GetInt64("size")
	c.APIReturn(500, "fsize not found", err)
	ob.SaveDir = c.GetString("savedir")
	ob.PacketNum, err = c.GetInt64("packetnum")
	dirpath, err := GetFilSaveDir()
	c.APIReturn(500, "文件保存目录获取失败", err)
	os.MkdirAll(dirpath+"/"+ob.SaveDir, os.ModeDir)
	f, err := os.Create(dirpath + "/" + ob.SaveDir + "/" + ob.FileName)
	c.APIReturn(500, "文件创建失败", err)
	defer f.Close()
	c.APIReturn(500, "文件填充失败", f.Truncate(ob.Size))
	c.APIReturn(500, "packet not found", err)
	c.APIReturn(500, "录入失败", md.AddFile(ob.ID, ob.FileName, ob.SaveDir, ob.Size, ob.PacketNum))
	c.APIReturn(200, "录入成功", nil)

}

//Uploadpacket 接收上传分片包
func (c *LoginController) Uploadpacket() {
	id := c.Ctx.Input.Param(":id")
	savepath, err := GetFilSavePath(id)
	c.APIReturn(500, "获取信息失败", err)
	offset, err := strconv.ParseInt(c.Ctx.Input.Param(":offset"), 10, 64)
	c.APIReturn(500, "获取offset失败", nil)
	f, err := os.OpenFile(savepath, os.O_RDWR, os.ModePerm)
	c.APIReturn(500, "打开文件失败", err)
	defer f.Close()
	_, err = f.WriteAt(c.Ctx.Input.RequestBody, offset)
	c.APIReturn(500, "打开写入失败", err)
	c.APIReturn(200, id, nil)

}

//UploadpacketDone 接收上传分片包
func (c *LoginController) UploadpacketDone() {
	id := c.Ctx.Input.Param(":id")
	status, _ := c.GetInt("status")
	c.APIReturn(500, "完成失败", md.FinshFile(id, status))
	c.APIReturn(200, "执行成功", nil)
}

func GetFilSavePath(id string) (string, error) {
	fs := md.Yserver{}
	bol, err := md.Localdb().Get(&fs)
	if err != nil || !bol {
		return "", err
	}
	if fs.SavePath == "" {
		fs.SavePath = "."
	}

	yp, err := md.FindFile(id)
	if err != nil {
		return "", err
	}
	savepath := fs.SavePath + "/" + yp.FileName
	return savepath, nil
}

func GetFilSaveDir() (string, error) {
	fs := md.Yserver{}
	bol, err := md.Localdb().Get(&fs)
	if err != nil || !bol {
		return "", err
	}
	if fs.SavePath == "" {
		fs.SavePath = "."
	}

	return fs.SavePath, nil
}

//Uploadlogs 存储日志查询
func (c *MainController) Uploadlogs() {
	id := c.Ctx.Input.Param(":id")
	page, _ := c.GetInt("page")
	count, _ := c.GetInt("count")
	if id == "" {
		yps, err := md.AllFile(page, count)
		c.APIReturn(500, "查询失败1", err)
		total, err := md.Filecount()
		c.APIReturn(500, "查询总数失败", err)
		rep := map[string]interface{}{"count": total, "data": yps}
		c.APIReturn(200, "查询成功", &rep)
	} else {
		yp, err := md.FindFile(id)
		c.APIReturn(500, "查询失败2", err)
		c.APIReturn(200, "查询成功", yp)
	}

}
